<?php
 
class Engine_Adapter
{
	protected static $_adapters = array();

	/**
	 * @var Engine_Core
	 */
	protected $_core;

	/**
	 * @param Engine_Core $core
	 */
	public function __construct($core)
	{
		$this->_core = $core;
	}
	
	/**
	 * @var string $type
	 * @var Engine_Core $core
	 * @return Engine_Adapter
	 */
	static public function factory($type, $core)
	{
		if (empty(self::$_adapters[$type]))
		{
			$adapterName  = $type . '_Adapter';

			if (false
				|| file_exists(APPLICATION_PATH . '/modules/' . str_replace('_', '/', $adapterName) . '.php')
				|| file_exists(APPLICATION_PATH . '/' . str_replace('_', '/', $adapterName) . '.php')
			) {
				self::$_adapters[$type] = new $adapterName($core);

				return self::$_adapters[$type];
			}
		}
	}

	/**
	 * @return Zend_Config
	 */
	public function getConfig()
	{
		return $this->_core->getConfig();
	}

	protected function getCommand($name, $params) {
		return  Engine_Db_Command::factory($this, $name, $params);
	}

	/**
	 * @return Engine_Core_Wrapper
	 */
	public function getEntry($params = array())
	{
		if (get_class($this) != 'Engine_Adapter') {
			$commandName = str_replace('_Adapter', '', get_class($this)) . '::Command_Select_Entry' . (!empty($params['criterion']) ? '_' . ucfirst($params['criterion']) : '');
		} else {
			$commandName = 'core::Command_Select_Entry' . (!empty($params['criterion']) ? '_' . ucfirst($params['criterion']) : '');
		}

		if (true
			&& !file_exists(APPLICATION_PATH . '/modules/' . str_replace(array('_', '::'), '/', $commandName) . '.sql.phtml')
			&& !file_exists(APPLICATION_PATH . '/'         . str_replace(array('_', '::'), '/', $commandName) . '.sql.phtml')
		) {
			$commandName = 'core::Command_Select_Entry' . (!empty($params['criterion']) ? '_' . ucfirst($params['criterion']) : '');
		}

		//var_dump($commandName);//die;
		
		$command = $this->getCommand($commandName, $params);

		//var_dump($command->toString());

		$result = $command->fetchAll()->first();

		return $result;
	}

	/**
	 * @return Engine_Core_Collection
	 */
	public function getCollection($params = array())
	{
		if (get_class($this) != 'Engine_Adapter') {
			$commandName = str_replace('_Adapter', '', get_class($this)) . '::Command_Select' . (!empty($params['criterion']) ? '_' . ucfirst($params['criterion']) : '');
		} else {
			$commandName = 'core::Command_Select' . (!empty($params['criterion']) ? '_' . ucfirst($params['criterion']) : '');
		}

		if (true
			&& !file_exists(APPLICATION_PATH . '/modules/' . str_replace(array('_', '::'), '/', $commandName) . '.sql.phtml')
			&& !file_exists(APPLICATION_PATH . '/'         . str_replace(array('_', '::'), '/', $commandName) . '.sql.phtml')
		) {
			$commandName = 'core::Command_Select' . (!empty($params['criterion']) ? '_' . ucfirst($params['criterion']) : '');
		}

		//var_dump($commandName);
		
		$command = $this->getCommand($commandName, $params);

		//var_dump($command->toString());

		$result = $command->fetchAll();

		if (!empty($params['paging'])) {
			$result->setPerPage($params['paging']['perPage']);
			$result->setPage($params['paging']['page']);
			$result->setCountAll($command->getCountAll());
		}

		return $result;
	}

	/**
	 * @var array $params
	 * @return int
	 */
	public function saveEntry($params = array())
	{
		if (!empty($params['id'])) {
			return $this->updateEntry($params);
		} else {
			return $this->insertEntry($params);
		}
	}

	/**
	 * @var array $params
	 * @return int
	 */
	public function updateEntry($params) {
		//var_dump($params);

		$commandName = 'core::Command_Update_ById';

		$command = $this->getCommand($commandName, $params);

//		var_dump($command->toString());die;

		$command->exec();

		return $params['id'];
	}

	/**
	 * @var array $params
	 * @return int
	 */
	public function insertEntry($params) {
		//var_dump($params);

		$commandName = 'core::Command_Insert_ById';

		$command = $this->getCommand($commandName, $params);

		//var_dump($command->toString());die;

		$command->exec();

		//var_dump($command->lastInsertId());die;

		return $command->lastInsertId();
	}

	/**
	 * @param array $params
	 * @return void
	 */
	public function deleteEntry($params = array())
	{
		//var_dump($params);

		$this->_deleteRelations($params);
		
		$commandName = 'core::Command_Delete_ById';

		$command = $this->getCommand($commandName, $params);

		//var_dump($command->toString());die;

		$command->exec();
	}

	/**
	 * @param array $params
	 * @return void
	 */
	public function _deleteRelations($params = array())
	{}
}